package guda.mrpc.core.codec;

import guda.mrpc.core.RpcRequest;
import guda.mrpc.core.RpcResponse;
import guda.mrpc.core.serialize.ObjectSerialize;
import guda.mrpc.core.transport.Hearbeat;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * Created by well on 17/6/3.
 */
public class RpcEncoder extends MessageToByteEncoder {

    private ObjectSerialize objectSerialize;

    public RpcEncoder(ObjectSerialize objectSerialize){
        this.objectSerialize=objectSerialize;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
        if (msg instanceof RpcRequest) {
            doEncodeRequest((RpcRequest) msg, out);
        } else if (msg instanceof RpcResponse) {
            doEncodeResponse((RpcResponse) msg, out);
        }else if(msg instanceof Hearbeat.NullHearbeat){
           out.writeBytes(Hearbeat.heartbeatContent());
        } else {
            throw new IllegalArgumentException(msg.getClass().getSimpleName());
        }
    }

    private void doEncodeRequest(RpcRequest request, ByteBuf out) throws Exception {
        byte[] bytes = objectSerialize.serialize(request);
        int length = bytes.length;
        out.writeShort(MsgHeader.MAGIC)
                .writeShort(MsgHeader.REQUEST)
                .writeInt(length)
                .writeBytes(bytes);
    }

    private void doEncodeResponse(RpcResponse response, ByteBuf out)  throws Exception{
        byte[] bytes = objectSerialize.serialize(response);
        int length = bytes.length;
        out.writeShort(MsgHeader.MAGIC)
                .writeShort(MsgHeader.RESPONSE)
                .writeInt(length)
                .writeBytes(bytes);
    }
}
